use std::{sync::mpsc, thread};
use std::sync::mpsc::Sender;

use anyhow::{anyhow, Result};

const NUM_PRODUCERS: usize = 3;

#[derive(Debug)]
struct Msg {
    idx: usize,
    value: usize,
}

fn main() -> Result<()> {
    let (tx, rx) = mpsc::channel();
    //创建producers
    for i in 0..NUM_PRODUCERS {
        let tx = tx.clone();
        thread::spawn(move || producer(i, tx));
    }
    drop(tx);
    //创建consumer
    let consumer = thread::spawn(move || {
        for msg in rx {
            println!("consumer:{:?}", msg);
        }
        println!("consumer extit");
        42
    });
    let secret = consumer.join().map_err(|e| anyhow!("Thread join error:{:?}",e))?;
    println!("over {}", secret);
    Ok(())
}

fn producer(idx: usize, tx: Sender<Msg>) -> Result<()> {
    let mut x = 0;
    loop {
        let value = rand::random::<usize>();
        let msg = Msg { idx, value };
        let sleep_time = rand::random::<u8>() as u64 * 10;
        //println!("{:?},{},{}", &msg, sleep_time,x);
        tx.send(msg)?;
        thread::sleep(std::time::Duration::from_millis(sleep_time));
        x += 1;
        if (x > 5) {
            break;
        }
    }
    Ok(())
}